package ua.khpi.si.kit49.diploma.controllers;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Set;

import org.apache.commons.lang.StringEscapeUtils;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.support.ReloadableResourceBundleMessageSource;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

import ua.khpi.si.kit49.diploma.core.Constants;
import ua.khpi.si.kit49.diploma.core.Forecast;
import ua.khpi.si.kit49.diploma.core.Weather;
import ua.khpi.si.kit49.diploma.db.dto.City;
import ua.khpi.si.kit49.diploma.db.dto.Connection;
import ua.khpi.si.kit49.diploma.service.CityService;

/**
 * Controller is in charge of operations with cities
 * 
 * @author netstalk3r
 * 
 */

@Controller
public class CitiesController {

	/**
	 * Logger
	 */
	private static final Logger log = Logger.getLogger(CitiesController.class);

	// /////////////////////////////////////////////////////////////////////////
	// mapping for methods
	// /////////////////////////////////////////////////////////////////////////
	private static final String CITIES_PAGE_MAPPING = "/cities";
	private static final String CITY_PAGE_MAPPING = "/city/{id}";
	// /////////////////////////////////////////////////////////////////////////

	/**
	 * service related to operation with cities
	 */
	@Autowired(required = true)
	private CityService cityService;

	/**
	 * message resource
	 */
	@Autowired(required = true)
	private ReloadableResourceBundleMessageSource messageSource;

	/**
	 * 
	 * @param model
	 *            model map
	 * @param loc
	 *            current localization
	 * @return page with all cities or error page
	 */
	@RequestMapping(value = CITIES_PAGE_MAPPING, method = RequestMethod.GET)
	public String getCitiesPage(ModelMap model, Locale loc) {
		log.info("Get All Cities");
		log.debug("Language - " + loc.getLanguage());
		try {
			List<City> listWithCities = cityService.getAllCities();
			Map<Integer, String> cities = new LinkedHashMap<Integer, String>();
			for (int i = 0; i < listWithCities.size(); i++) {
				String cityName = messageSource.getMessage("company.city."
						+ listWithCities.get(i).getName(), null,
						Constants.DEFAULT_MESSAGE, loc);
				cityName = StringEscapeUtils.unescapeJava(cityName);
				cities.put(listWithCities.get(i).getId(), cityName);
			}
			model.put("citiesList", cities);
			return Constants.CITIES_PAGE;
		} catch (Exception e) {
			e.printStackTrace();
			log.error(e.getMessage());
			String errorMessage = messageSource.getMessage(e.getMessage(),
					null, e.getMessage(), loc);
			errorMessage = StringEscapeUtils.unescapeJava(errorMessage);
			model.put("errorMessage", errorMessage);
			return Constants.ERROR_PAGE;
		}
	}

	/**
	 * method for getting page with information about particular city
	 * 
	 * @param id
	 *            of particular city
	 * @param model
	 *            model map
	 * @param loc
	 *            current localization
	 * @return page with information about current city or error page
	 */
	@RequestMapping(value = CITY_PAGE_MAPPING, method = RequestMethod.GET)
	public String getCityInformation(@PathVariable("id") String id,
			ModelMap model, Locale loc) {
		Integer cityId = null;
		try {
			log.info("Information about city with id = " + id);
			try {
				cityId = Integer.parseInt(id);
			} catch (NumberFormatException e) {
				throw new NumberFormatException(
						"company.error.city.illegal.id.format");
			}
			City city = cityService.getCityById(cityId);
			String name = messageSource.getMessage(
					"company.city." + city.getName(), null,
					Constants.DEFAULT_MESSAGE, loc);
			name = StringEscapeUtils.unescapeJava(name);
			model.put("cityName", name);
			Set<Connection> connections = city.getConnectionsFinish();
			Iterator<Connection> iterator = connections.iterator();
			Map<Integer, String> connects = new LinkedHashMap<Integer, String>();
			while (iterator.hasNext()) {
				City cityStart = iterator.next().getCityStart();
				String nameCityStart = messageSource.getMessage("company.city."
						+ cityStart.getName(), null, Constants.DEFAULT_MESSAGE,
						loc);
				nameCityStart = StringEscapeUtils.unescapeJava(nameCityStart);
				connects.put(cityStart.getId(), nameCityStart);
			}
			model.put("connects", connects);

			Weather weather = city.getWeather();
			String direction = messageSource.getMessage(
					"company.weather.wind.direction."
							+ weather.getWindDirection(), null,
					Constants.DEFAULT_MESSAGE, loc);
			direction = StringEscapeUtils.unescapeJava(direction);
			model.put("windDirection", direction);

			List<Forecast> forecasts = weather.getForecast();
			List<String> days = new ArrayList<String>();
			for (int i = 0; i < forecasts.size(); i++) {
				Forecast forecast = forecasts.get(i);
				String day = messageSource.getMessage(
						"company.weather.forecast.day." + forecast.getDay(),
						null, Constants.DEFAULT_MESSAGE, loc);
				day = StringEscapeUtils.unescapeJava(day);
				days.add(day);
			}
			model.put("days", days);

			model.put("city", city);
			return Constants.CITY_PAGE;
		} catch (Exception e) {
			e.printStackTrace();
			log.error(e.getMessage());
			String errorMessage = messageSource.getMessage(e.getMessage(),
					null, e.getMessage(), loc);
			errorMessage = StringEscapeUtils.unescapeJava(errorMessage);
			model.put("errorMessage", errorMessage);
			return Constants.ERROR_PAGE;
		}
	}
}
